
# -*- coding:utf-8 -*-
'''
-------------------------------------------------
   Description :  txt2p model evaluate
   Author :       liupeng
   Date :         2020-03-02
-------------------------------------------------
'''

import os 
import re
import sys
import time
import keras
import numpy as np
from keras import backend as K
# warnings.filterwarnings(action='ignore', category=UserWarning, module='gensim')# 忽略警告
np.random.seed(2019)
from bert4keras.snippets import sequence_padding, DataGenerator
from bert4keras.tokenizer import Tokenizer


def Precision(y_true, y_pred):
    """精确率"""
    tp= K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))  # true positives
    pp= K.sum(K.round(K.clip(y_pred, 0, 1))) # predicted positives
    precision = tp/ (pp+ K.epsilon())
    return precision
    
def Recall(y_true, y_pred):
    """召回率"""
    tp = K.sum(K.round(K.clip(y_true * y_pred, 0, 1))) # true positives
    pp = K.sum(K.round(K.clip(y_true, 0, 1))) # possible positives
    recall = tp / (pp + K.epsilon())
    return recall


class Evaluator(keras.callbacks.Callback):
    def __init__(self, valid_generator, test_generator, model):
        self.best_val_acc = 0.
        self.best_val_pre = 0.
        self.best_val_recall = 0.
        self.model = model
        self.valid_generator = valid_generator
        self.test_generator = test_generator

    def on_epoch_end(self, epoch, logs=None):
        val_acc = self.model.evaluate(self.valid_generator.forfit(), steps=len(self.valid_generator), verbose=0)
        if val_acc[1] > self.best_val_acc:
            self.best_val_acc = val_acc[1]
            #self.best_val_pre = val_acc[2]
            #self.best_val_recall = val_acc[3]
            self.model.save_weights('best_model.weights')
        # self.model.save_weights( './weights/{}_model.weights'.format(epoch) )
        test_acc = self.model.evaluate(self.test_generator.forfit(), steps=len(self.test_generator), verbose=0)
        print(u'val_acc: %.5f, best_val_acc: %.5f, test_acc: %.5f'
              % (val_acc[1], self.best_val_acc, test_acc[1])) 
        #print(u'val_pre: %.5f, best_val_pre: %.5f, test_pre: %.5f'
        #      % (val_acc[2], self.best_val_pre, test_acc[2])) 
        #print(u'val_recall: %.5f, best_val_recall: %.5f, test_recall: %.5f\n'
        #      % (val_acc[3], self.best_val_recall, test_acc[3])) 

